<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>PrettyProlog implementation details - the Engine Module</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
<meta name="generator" content="Emacs">
<style type="text/css">
@import url("../style.css");
</style>
</head>
<body>
<div id="container">
    <div id="header">
        <h1>PrettyProlog - the Engine Module</h1>
    </div>
    <div id="content">
	<p align="left">
	    The Engine Module (package <code>prettyprolog.engine</code>) is the main PrettyProlog module. It contains the Engine class as well as many helper classes such as Theory, Goal and Clause. This module contains also two sub-modules: the <a href="engine_listeners.html">Event Listeners sub-module</a> (package <code>prettyprolog.engine.listeners</code>), which provides classes and interfaces used to attach listeners to the Engine, the Stack, and the Theory; and the <a href="engine_syspreds.html">Syspreds sub-module</a> (package <code>prettyprolog.engine.syspreds</code>), which defines the built-in system predicates and gives the programmer the possibility to easily add new ones.<br /><br />
	Let's examine in detail the classes that make up the Engine Module:
	<ul>
	  <li><b>Unifier.</b> The class Unifier provides a single public method, unify(Term, Term), that returns a Substitution that unifies the two Terms passed as arguments, or null if they aren't unifiable.<br />
	        <b>Why?</b> The Unifier exists as a separate class for reasons of modularity and extensibility. If a programmer is modifying PrettyProlog by, for example, adding new types of Terms, all (s)he has to do to integrate the new data types with the unification mechanism is to subclass Unifier, write one or more methods to handle his/hers new Terms, and override the public unify(Term, Term) method to recognize the new data types - (s)he hasn't to reimplement the whole unification mechanism.</li>
	  <li><b>Clause.</b> A Clause is an object made of a Callable (the head) and a body, again a nameless Callable. Clauses are the rules that form Theories.</li>
	  <li><b>Theory.</b> This class implements a list of Clauses, with the usual operations for adding to, removing from, or navigating through the list. The only notable difference from a standard list is the nextClause() method, used by the engine to get a copy of the next clause (starting from a given index) whose head unifies with a certain term. Also, it is possible to add TheoryListeners to instances of this class, so that the events associated with assert, retract and clause selection can be caught.</li>
	  <li><b>Frame.</b> A Frame is a single piece of data that is contained in a Stack. Frames hold the current Goal and Substitution, the index from which the Engine will search for the next clause on backtracking, and a String (used only for display purposes) that is the printed representation of the Clause used to derive the current Goal.</li>
	  <li><b>Stack.</b> In addition to the usual stack operations, this class can register StackListeners which are notified of every change in the Stack's state.<br />
              <b>Why?</b> PrettyProlog's objective is to implement a simple Prolog interpreter following the algorithms studied in prof. Martelli's course. The solving algorithm we studied was stack-based, hence the presence of a Stack. An explicit stack is also useful to inspect the behaviour of the Engine, since you can associate listeners with the Stack to capture events such as push, pop, cut, and stack reset.<br />
	  The stack frames we studied in prof. Martelli's lessons were triplets of a goal, a substitution, and an integer index used for backtacking. The Frames used by PrettyProlog, in addition to these info, maintain a String representation of the Clause used to obtain the Goal, and a &quot;cut mark&quot; used by the Cut (!) special system predicate to recognize which frames must be &quot;cut&quot;.</li>
	  <li><b>Goal.</b> A Goal is a list of Callables and/or Variables. At the time it is executed, a Variable must be bound to a Callable, else the Engine will signal an error.</li>
	  <li><b>Engine.</b> This is the main class of this module. It is explained in detail in <a href="engine_class.html">this page</a>.</li>
	</ul>
	<br />
	For further info, see the javadocs.
	</p>
	<p align="left">
	    <h4>Extending PrettyProlog: Tweaking engine functionality</h4>
	    The preferred way to alter PrettyProlog engine's behaviour is not subclassing or, even worse, rewriting classes in this module; instead, if possible you should use the provided event-driven interfaces or the system predicate submodule to achieve your goal.<br />
	    The only exception to this is if you want a new data type to be recognized by the Unifier; in this case, you have to subclass Unifier and override its unify(Term, Term) method so to hijack unifications concerning the new data type to a new private method added by you. An example:
	    <pre>
public class MyUnifier extends Unifier {

  public Substitution unify(Term t1, Term t2) {
    if(t1 instanceof MyNewDataType)
      return myNewUnify((MyNewDataType)t1, t2);
    else if(t2 instanceof MyNewDataType)
      return myNewUnify((MyNewDataType)t2, t1);
    else return super.unify(t1, t2);
  }

  private Substitution myNewUnify(MyNewDataType t1, Term t2) {
    /* do your stuff here... */
  }

}
	    </pre>
	</p>
    </div>
    <div id="footer"><a href="../index.html">General info</a> | <a href="../javadoc/index.html">Javadocs</a> | <a href="index.html">Implementation details</a></div>
</div>
</body>
</html>